﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace QuantumFractals
{
    public partial class FormulaForm : Form
    {
        NumberFormatInfo englishNumber = new CultureInfo("en-US", false).NumberFormat;
        private MethodInfo method = null;
        private string lastFormula = "";

        public string Formula
        {
            get 
            { 
                return txtFormula.Text; 
            }
            set 
            { 
                txtFormula.Text = value;
                btnCalculate_Click(this, new EventArgs());
            }
        }

        public Dictionary<string, string> FormulaConstants
        {
            get
            {
                Dictionary<string, string> dict = new Dictionary<string,string>();
                foreach(string s in txtFormulaConstants.Lines)
                {
                    string[] pair = s.Split(new char[] {'='}, 2);
                    if (pair.Length == 2)
                        dict.Add(pair[0].Trim(), pair[1].Trim());
                }
                return dict;
            }
            set
            {
                txtFormulaConstants.Text = "";
                foreach(string k in value.Keys)
                    txtFormulaConstants.Text += k + " = " + value[k] + "\r\n";
                btnCalculate_Click(this, new EventArgs());
            }
        }

        public bool VariableXEnabled
        {
            get
            {
                return txtVariableX.Enabled;
            }
            set
            {
                txtVariableX.Enabled = value;
            }
        }

        public FormulaForm()
        {
            InitializeComponent();
        }

        private void comConstant_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                string[] s = comConstant.Text.Split('=');
                if (s.Length > 0)
                    txtFormula.SelectedText = s[0].Trim();
            }
        }

        private void comFunction_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                string[] s = comFunction.Text.Split('-');
                if (s.Length > 0)
                    txtFormula.SelectedText = s[0].Trim();
            }
        }

        private void comExampleFormula_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                txtFormula.SelectedText = comExampleFormula.Text.Trim();
        }

        private void txtFormula_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnCalculate_Click(sender, e);
        }

        private void btnCalculate_Click(object sender, EventArgs e)
        {
            if (txtFormula.Text.Trim() != lastFormula && txtFormula.Text.Trim() != "")
            {
                method = Evaluator.AddFormula(txtFormula.Text, "double", FormulaConstants, 
                    new Dictionary<string,string> { { "X", "double" } });
                lastFormula = txtFormula.Text.Trim();
            }
            if (method != null && txtVariableX.Text.Trim() != "")
            {
                object[] args = { Convert.ToDouble(txtVariableX.Text, englishNumber) };
                double result = (double)method.Invoke(null, args);
                txtResult.Text = result.ToString(englishNumber);
            }
        }

        private void txtVariableX_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnCalculate_Click(sender, e);
        }

    }
}